import React, { Component, PropTypes } from 'react'
import Touchable from 'rc-touchable'

// 空操作
function noop() {}

/**
 * When click and hold on a button/container - the speed of auto changin the value.
 */
const SPEED = 1000

/**
 * When click and hold on a button/container - the delay before auto changin the value.
 */
const DELAY = 600

const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar)

function isString(str) {
  return typeof str === 'string'
}

// Insert one space between two chinese characters automatically.
function insertSpace(child) {
  if (isString(child.type) && isTwoCNChar(child.props.children)) {
    return React.cloneElement(child, {},
      child.props.children.split('').join(' '))
  }
  if (isString(child)) {
    if (isTwoCNChar(child)) {
      child = child.split('').join(' ')
    }
    return <span>{child}</span>
  }
  return child
}

export default class TouchableContainer extends Component {
  constructor() {
    super()
    this.touch = this.touch.bind(this)
    this.stop = this.stop.bind(this)
    this.step = this.step.bind(this)
  }
  componentWillUnmount() {
    this.stop()
  }
  render() {
    const { children, className } = this.props
    const kids = React.Children.map(children, insertSpace)
    return (
      <Touchable>
        <div
          className={className}
          onTouchStart={this.touch}
          onTouchEnd={this.stop}
          onClick={this.props.onClick}
        >
          {kids}
        </div>
      </Touchable>
    )
  }
  touch(e, recursive) {
    if (e.persist) {
      e.persist()
    }
    this.stop()
    this.step(e)
    this.autoButtonTimer = setTimeout(() => {
      this.touch(e, true)
    }, recursive ? SPEED : DELAY)
  }
  stop() {
    if (this.autoButtonTimer) {
      clearTimeout(this.autoButtonTimer)
    }
  }
  step(e) {
    if (e) {
      e.preventDefault()
    }
    this.props.onClick()
  }
}

TouchableContainer.defaultProps = {
  onClick: noop,
  className: '',
}

TouchableContainer.propTypes = {
  onClick: PropTypes.func,
  className: PropTypes.string,
}